﻿using System;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using SQLServices.Repository;

namespace SQLRunnerSMO
{
    public class SqlConnSmo : ISQLDBConn
    {
        private readonly ServerConnection SqlConn;

        public SqlConnSmo(SqlServerSmo server)
        {
            SqlConn = server.SqlServer.ConnectionContext;
            SQLConnection = server;
        }

        #region Implementation of ISQLDBConn

        public string DatabaseName { 
            get
            {
                return SqlConn.DatabaseName;
            } 
            set
            {
                if (value == null) throw new ArgumentNullException("value");
                SQLConnection.GetDatabase(value);
            }
        }

        public ISQLConnection SQLConnection { get; private set; }

        /// <summary>
        /// Use it to create a new connection to the SQLServer
        /// using the current connection settings
        /// </summary>
        /// <returns>A new connection to the same SQL Server and database</returns>
        public ISQLDBConn Clone()
        {
            var server = new SqlServerSmo();
            server.OpenConnection(
                SQLConnection.ServerName,
                SQLConnection.UserId,
                SQLConnection.Password,
                SQLConnection.LoginSecure);

            return server.GetDatabase(DatabaseName);        
        }

        public void Execute(string sqlScript)
        {
            SqlConn.ExecuteNonQuery(sqlScript);    
        }

        public long GetTranCount()
        {
            const string sqlScript = "SELECT @@TranCount";
            var result = SqlConn.ExecuteScalar(sqlScript);
            
            if (result == null) return -1;
            return (int) result;            
            //return results.GetColumnLong(1, 1);
        }

        public string GetToken()
        {
            const string sqlScript = "DECLARE @token varchar(255) " +
                                     "exec sp_getbindtoken @token output " +
                                     "Select @token token";
            var result = SqlConn.ExecuteScalar(sqlScript);
            if (result == null) return null;
            return (string) result;
        }

        public void SetToken(string token)
        {
            var sqlScript = string.Format("exec sp_bindsession '{0}'", token);
            SqlConn.ExecuteNonQuery(sqlScript);
        }

        /// <summary>
        /// Delegates to the connection manager to see if a better exception
        /// can be retrieved in a single line
        /// </summary>
        /// <param name="exception">Normally an exception ocurred executing SQL scripts</param>
        /// <returns>A single line describing the script executiong problem</returns>
        public string ParseException(Exception exception)
        {
            if (exception is ExecutionFailureException &&
                exception.InnerException != null &&
                exception.InnerException is SqlException)
            {
                return exception.InnerException.Message;
            }

            return null;
        }

        #endregion
    }
}
